<?php
/**
 * WSCORE Classes
 * @author wsfuyibing <websearch@163.com>
 * @source [PATH]project/base/classes.php
 * @date 2013-12-23
 */
defined('WSCORE') || exit('Access-Denied');
/**
 * 公共静态方法
 */
class wsc{
	/**
	 * 属性描述
	 * @access private array $_module, 模块记录
	 * @access private array $_module_language, 模块语言
	 * @access private array $_module_setting, 模块配置
	 * @access private array $_seo, SEO三要素
	 */
	private static $_module = array();
	private static $_module_language = array();
	private static $_module_setting = array();
	private static $_seo = array('title' => '', 'keywords' => '', 'description' => '');

	/**
	 * [A]
	 * @access public a2s, Array&String互换
	 */
	public static function a2s($p = array(), $d = false){
		/**
		 * 数组转字符串
		 */
		if ($d){
			if (preg_match("/^array/", $p)){
				$r = eval('return ' . $p . ';');
			}
			return isset($r) && is_array($r) ? $r : array();
		}
		$r = 'array(';
		$c = '';
		if (is_array($p)){
			foreach ($p as $k => $v){
				$r .= $c;
				$c = ', ';
				$r .= "'{$k}' => ";
				/**
				 * 数据类型
				 */
				if (is_array($v)){
					/**
					 * 数组递归
					 */
					$r .= self::a2s($v);
				}
				else if (is_numeric($v)){
					$r .= "'" . $v . "'";
				}
				else if (is_string($v)){
					$v = addslashes(stripslashes($v));
					$v = preg_replace("/((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)/", "'.\\1.'", $v);
					$r .= "'" . $v . "'";
				}
				else{
					$r .= "NULL";
				}
			}
		}
		$r .= ')';
		return $r;
	}
	/**
	 * [H]
	 * @access public hash, 生成随机字符
	 */
	public static function hash($t = 2, $l = 8){
		/**
		 * 生成随机字符串
		 * @param int $t, 类型
		 *        0:数字
		 *        1:字母
		 *        2:综合
		 * @param int $l, 长度(4~128)
		 */
		$c = array(
			'i' => array(
				0, 1, 2, 3, 4, 5, 6, 7, 8, 9
			), 'c' => array(
				'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
			)
		);
		is_numeric($t) && $t = (int) $t;
		is_numeric($l) && $l = (int) $l;
		$l < 4 && $l = 4;
		$l > 128 && $l = 128;
		/**
		 * Options
		 */
		switch ($t){
			case 0 :
				$s = $c['i'];
				break;
			case 1 :
				$s = $c['c'];
				break;
			default :
				$s = array_merge($c['i'], $c['c']);
				break;
		}
		$n = count($s) - 1;
		/**
		 * Length
		 */
		$r = '';
		for ($i = 0; $i < $l; $i++){
			$r .= $s[mt_rand(0, $n)];
		}
		return $r;
	}
	/**
	 * [I]
	 * @access public init, 初始化
	 * @access public isajax, 初始化
	 * @access public isarr, 初始化
	 * @access public ispost, 初始化
	 */
	public static function init(){
		/**
		 * 全局语言与配置
		 */
		self::$_module_language = require_once WSCORE_PATH . '/language/wscore.php';
		self::$_module_setting = require_once WSCORE_PATH . '/setting/wscore.php';
		/**
		 * @const CLIENT_TIME, 当前UNIX时间戳
		 */
		define('CLIENT_TIME', time());
		return true;
		/**
		 * @const CLIENT_IP, 客户端IP地址
		 */
		$_CLIENT_IP = I('v.REMOTE_ADDR');
		if (!$_CLIENT_IP && function_exists('getenv')){
			$_CLIENT_IP = getenv('REMOTE_ADDR');
			$_CLIENT_IP || $_CLIENT_IP = getenv('HTTP_CLIENT_IP');
			if (!$_CLIENT_IP){
				$chide = getenv('HTTP_X_FORWARDED_FOR');
				if ($chide){
					list($_CLIENT_IP) = explode(',', $chide);
				}
			}
		}
		$_CLIENT_IP || $_CLIENT_IP = '0.0.0.0';
		define('CLIENT_IP', $_CLIENT_IP);
		/**
		 * @const CLIENT_OS, 操作系统(如: Windows, Andriod, iPhone)
		 * @const CLIENT_OS_VERSION, 操作系统版本号
		 * @const CLIENT_BROWSER, 浏览器内核(如: webkit, moz, ms)
		 * @const CLIENT_BROWSER_NAME, 浏览器名称(如: IE10, Chrome, Safari, Firefox)
		 * @const CLIENT_BROWSER_VERSION, 浏览器版本号
		 */
		$_CLIENT_OS = 'Windows';
		$_CLIENT_OS_VERSION = 0;
		$_CLIENT_BROWSER = 'webkit';
		$_CLIENT_BROWSER_NAME = 'Chrome';
		$_CLIENT_BROWSER_VERSION = 0;
		$_CLIENT_USERAGENT = I('v.HTTP_USER_AGENT');
		if (!$_CLIENT_USERAGENT && function_exists('getenv')){
			$_CLIENT_USERAGENT = getenv('HTTP_USER_AGENT');
		}
		if ($_CLIENT_USERAGENT){
			/**
			 * IE8(+)
			 * @example ms, MSIE
			 */
			if (preg_match("/trident\/([\w.]+)/i", $_CLIENT_USERAGENT, $_m)){
				$_m[1] = (int) $_m[1];
				$_m[1] += 4;
				$_CLIENT_BROWSER = $_m[1] > 9 ? 'ms' : 'ie' . $_m[1];
				$_CLIENT_BROWSER_NAME = 'IE ' . $_m[1];
				$_CLIENT_BROWSER_VERSION = (string) $_m[1];
			}
			else /**
			 * IE7(-)
			 */
			if (preg_match("/(msie)(\s*)([\w.]+)/i", $_CLIENT_USERAGENT, $_m)){
				$_m[3] = (int) $_m[3];
				$_CLIENT_BROWSER = $_m[3] > 9 ? 'ms' : 'ie' . $_m[3];
				$_CLIENT_BROWSER_NAME = 'IE ' . $_m[3];
				$_CLIENT_BROWSER_VERSION = (string) $_m[3];
			}
			/**
			 * 非IE
			 */
			else{
				foreach (array(
					'webkit' => 'AppleWebKit', 'moz' => 'Gecko', 'o' => 'Opera'
				) as $nk => $nv){
					if (preg_match("/(" . $nv . ")\/([\w.]+)/i", $_CLIENT_USERAGENT, $_m)){
						$_CLIENT_BROWSER = $nk;
						$_CLIENT_BROWSER_VERSION = (string) $_m[2];
						break;
					}
				}
			}
			/**
			 * 浏览器名称/版本
			 * @attention Sogou, 360隐藏了名称(伪装成IE/Webkit内核)
			 * 不能直接分配名称, 需要再加工, 有兴趣的可
			 * 　　　　　　以二次开发了, 这里只设置几个主流的
			 */
			foreach (array(
				'Maxthon', 'QQBrowser', '360se', 'Firefox', 'Navigator', 'OPR', 'Chrome', 'Safari', 'Opera'
			) as $n){
				if (preg_match("/(" . $n . ")\/([\w.]+)/i", $_CLIENT_USERAGENT, $_m)){
					if (preg_match("/version\/([\w.]+)/i", $_CLIENT_USERAGENT, $_v)){
						$_m[2] = $_v[1];
					}
					$_CLIENT_BROWSER_NAME = $_m[1] . ' ' . $_m[2];
					break;
				}
			}
			/**
			 * 操作系统类型/版本
			 */
			foreach (array(
				'Windows' => "/(windows)([a-z\s]*)([0-9.]+)/i", 'Android' => "/(Android)([;\s]*)([\w.]*)/i", 'Symbian' => "/(Symbian)/i", 'Linux' => "/(Linux)/i", 'Unix' => "/(Unix)/i", 'iPhone' => "/CPU (iphone) OS(\s*)([0-9_]+)/i", 'iPad' => "/CPU(\s*)OS(\s*)([0-9_]+)/i", 'MeeGo' => "/(MeeGo)/i", 'Mac' => "/(Mac)([a-z\s]*)([0-9.]+)/i", 'BlackBerry' => "/(BB[0-9]+|PlayBook|BlackBerry)/"
			) as $_ok => $_ov){
				if (preg_match($_ov, $_CLIENT_USERAGENT, $_m)){
					$_CLIENT_OS = $_ok;
					$_m[3] = isset($_m[3]) ? str_replace('_', '.', $_m[3]) : '0.0';
					$_CLIENT_OS_VERSION = $_m[3];
					break;
				}
			}
		}
		/**
		 * 客户端常量定义
		 */
		define('CLIENT_OS', $_CLIENT_OS);
		define('CLIENT_OS_VERSION', $_CLIENT_OS_VERSION);
		define('CLIENT_BROWSER', $_CLIENT_BROWSER);
		define('CLIENT_BROWSER_NAME', $_CLIENT_BROWSER_NAME);
		define('CLIENT_BROWSER_VERSION', $_CLIENT_BROWSER_VERSION);
		/**
		 * Yii框架SESSION
		 */
		$_SESS = new CHttpSession();
		$_SESS->setCookieParams(S('WSCORE_SESSION'));
		$_SESS->open();
		/**
		 *
		 * @var string $hash, 识别符(干扰因子)
		 * @var int time, 建立时间
		 * @var int uid, 会员编号
		 */
		I('s.hash') === null && I('s.hash', self::hash());
		I('s.time') === null && I('s.time', CLIENT_TIME);
		I('s.uid') === null && I('s.uid', 0);
	}
	public static function isajax(){
		return A('request')->getIsAjaxRequest();
	}
	public static function isarr(){
		/**
		 *
		 * @var int $_ai, 参数数量
		 * @var array $_as, 参数数组
		 *      array $_as[0], 首参数必须为数组
		 *      string $_as[1], [可选]
		 *      必须为字符串(数组键值)
		 *      以点号分隔
		 *      如: isarr($a, 'k1.k2')
		 *      any $_as[2], [可选]
		 *      比较
		 *      返回布尔
		 * @return null, 未定义或无效返回
		 */
		if (($_ai = func_num_args()) < 1){
			return null;
		}
		$_as = func_get_args();
		if (!is_array($_as[0])){
			return $_ai > 2 ? false : null;
		}
		/**
		 * 定义与比较
		 */
		if ($_ai > 1){
			/**
			 * 已定义检查
			 */
			$_tmp = & $_as[0];
			$_skip = false;
			foreach (explode('.', $_as[1]) as $_k){
				$_k = trim($_k);
				if ($_k != ''){
					if (preg_match("/^([0-9]+)$/", $_k)){
						$_k = (int) $_k;
					}
					if (isset($_tmp[$_k])){
						$_tmp = & $_tmp[$_k];
					}
					else{
						$_skip = true;
						break;
					}
				}
			}
			/**
			 * 未定义退出
			 */
			if ($_skip){
				return $_ai > 2 ? false : null;
			}
			/**
			 * 返回比较结果
			 * @return boolean
			 */
			if ($_ai > 2){
				/**
				 * 范围比较
				 */
				if (preg_match("/([\<=\>]+)([\w\-.]+)/", $_as[2], $m) && is_numeric($_tmp)){
					/**
					 * 转换类型
					 */
					$_tmp *= 1;
					$m[2] *= 1;
					/**
					 * 返回比较
					 */
					if ($m[1] == '<'){
						return $_tmp < $m[2];
					}
					else if ($m[1] == '<='){
						return $_tmp <= $m[2];
					}
					else if ($m[1] == '>'){
						return $_tmp > $m[2];
					}
					else if ($m[1] == '>='){
						return $_tmp >= $m[2];
					}
					else if ($m[1] == '='){
						return $_tmp == $m[2];
					}
					else{
						return false;
					}
				}
				/**
				 * 字符比较
				 */
				else{
					return $_tmp === $_as[2];
				}
			}
			/**
			 * 返回读取值
			 * @return any
			 */
			return $_tmp;
		}
		/**
		 * 直接返回
		 * @return array
		 */
		return $_as[0];
	}
	public static function ispost(){
		/**
		 * 是否为POST方式
		 * @example wsc::ispost()
		 * @example wsc::ispost('field')
		 * @return boolean true
		 */
		if (A('request')->getIsPostRequest()){
			/**
			 * 带参数
			 */
			if (($_ai = func_num_args()) > 0){
				$_as = func_get_args();
				return I('p.' . $_as[0]);
			}
			/**
			 * 仅检查POST
			 */
			return true;
		}
		/**
		 * GET方式
		 * @return boolean false
		 */
		return false;
	}
	public static function ispostspam(){
		$inputs = array();
		$inputs['formsubmit'] = time();
		$inputs['formsecret'] = md5(I('v.HTTP_USER_AGENT'));
		$inputs['formsecret'] = md5(substr(md5($inputs['formsecret']), 8, 16).$inputs['formsubmit']);
		$result  = ''; foreach ($inputs as $k => $v){
		$result .= '<input type="hidden" name="'.$k.'" value="'.$v.'" />'; }
		return $result;
	}
	/**
	 * [M]
	 * @access public mkdir, 建立目录
	 * @access public module, 加载模块
	 * @access public module_language, 模块语言
	 * @access public module_setting, 模块设置
	 */
	public static function mkdir($p, $m = '0777'){
		/**
		 * 接受参数
		 * @param string $p, 完整路径
		 * @param string $m, 目录属性(Linux)
		 */
		is_string($p) && $p || $p = null;
		if (!$p){
			E('MKDIR_INVALID');
		}
		/**
		 * 路径检查
		 */
		if (preg_match("/\.([a-z0-9_\-]+)$/i", $p)){
			$p = dirname($p);
		}
		if (is_dir($p)){
			return true;
		}
		/**
		 * 创建目录
		 */
		$m = (string) $m;
		$m || $m = '0777';
		/**
		 * 目录递归
		 * @var int $_fc, folderComma
		 * @var string $_fn, folderName
		 * @var array $_fp, folderPath
		 */
		$_fp = $_fc = '';
		$p = str_replace(array(
			'/', '\\'
		), DIRECTORY_SEPARATOR, $p);
		foreach (explode(DIRECTORY_SEPARATOR, $p) as $_fn){
			$_fp .= $_fc;
			$_fc = DIRECTORY_SEPARATOR;
			$_fp .= $_fn;
			is_dir($_fp) || mkdir($_fp, $m);
			if (!is_dir($_fp)){
				break;
			}
		}
		if (is_dir($p)){
			return true;
		}
		/**
		 * 失败返回
		 */
		E('MKDIR_FAIL');
	}
	public static function module($p, $_err = false){
		/**
		 * 模块路径与名称
		 * @param string $p, 模块参数
		 *        eg: test
		 *        eg: test/name
		 */
		$_name = $_path = ''; foreach (explode('/', $p) as $_t){
			$_t = trim($_t); if ($_t){
				$_t = strtolower($_t);
				$_path .= '/' . $_t;
				$_name .= ucfirst($_t);
			}
		} $_name .= 'Module'; $_path .= '.php';
		/**
		 * 重载
		 */
		if (isset(self::$_module[$_name])){
			return new $_name();
		} if ($_err){
			E('MODULE_LOAD_FILE', array('module' => $p));
		}
		/**
		 * 首载(初始化)
		 * @var string $_module, 模块路径
		 * @var string $_language, 语言路径
		 * @var string $_setting, 配置路径
		 */
		$_module = WSCORE_PATH . '/module' . $_path; if (file_exists($_module)){
			$_language = WSCORE_PATH . '/language' . $_path;
			$_setting = WSCORE_PATH . '/setting' . $_path; if (file_exists($_language)){
				self::$_module_language = array_merge(self::$_module_language, include $_language);
			} if (file_exists($_setting)){
				self::$_module_setting = array_merge(self::$_module_setting, include $_setting);
			} self::$_module[$_name] = $_module; include $_module; return self::module($p, true);
		} E('MODULE_NOTFOUND', array('module' => $p));
	}
	public static function module_language(){
		/**
		 * 加载语言包
		 * @var int $_ai, 参数数量
		 * @param array $_as, 参数数组
		 */
		if (($_ai = func_num_args()) < 1){
			return null;
		}
		$_as = func_get_args();
		if (preg_match("/([a-z0-9_]+)/i", $_as[0])){
			if ($_ai > 1){
				self::$_module_language[$_as[0]] = $_as[1];
			}
			return isset(self::$_module_language[$_as[0]]) ? self::$_module_language[$_as[0]] : null;
		}
	}
	public static function module_setting(){
		/**
		 * 加载配置
		 * @var int $_ai, 参数数量
		 * @param array $_as, 参数数组
		 */
		if (($_ai = func_num_args()) < 1){
			return null;
		}
		$_as = func_get_args();
		if (preg_match("/([a-z0-9_]+)/i", $_as[0])){
			if ($_ai > 1){
				self::$_module_setting[$_as[0]] = $_as[1];
			}
			return isset(self::$_module_setting[$_as[0]]) ? self::$_module_setting[$_as[0]] : null;
		}
	}
	
	/**
	 * [S]
	 * @access public seoadd, 添加SEO属性
	 * @access public seoload, 载入SEO文件
	 */
	public static function seoadd($k, $v){
	}
	/**
	 * 加载语言包
	 */
	public static function seoload($k){
		/**
		 * 解析语言位置
		 */
		$k && $k = str_replace(array('/', '\\'), '_', $k);
		$a = explode('_', $k);
		$f = WSCORE_PATH.'/language/seo/'.$a[0].'.php';
		$l = array(); file_exists($f) && 
		$l = require_once $f;
		/**
		 * 是否定义
		 */
		$z = self::isarr($l, $k); if (self::isarr($z, 'title')){
			self::$_seo = $z;
		}
		/**
		 * 未定义时载入默认
		 */
		self::$_seo['title'] || self::$_seo['title'] = L('SEO_TITLE');
		self::$_seo['keywords'] || self::$_seo['keywords'] = L('SEO_KEYWORDS');
		self::$_seo['description'] || self::$_seo['description'] = L('SEO_DESCRIPTION');
		return self::$_seo;
	}
	/**
	 * [W]
	 * @access public wscform, 表单回调[jQuery]
	 */
	public static function wscform(){
		/**
		 * 表单返回
		 */
		if (($_ai = func_num_args()) > 0){
			/**
			 * 表单完成
			 * @example wsc::wscform(true)
			 * @example wsc::wscform(true, 'http://www.example.com')
			 * @example wsc::wscform(true, 'http://www.example.com', 'Information')
			 * 表单字段出错
			 * @example wsc::wscform('name')
			 * @example wsc::wscform('name', 'Reason')
			 */
			$_as = func_get_args();
			/**
			 * 回调方法
			 */
			$_fn = 'parent.'; if (A('request')->getIsAjaxRequest()){
				$_fn = '';
			} $_fn .= 'jQuery.fn.wscform(';
			/**
			* JS参数
			*/
			$comma = ''; foreach ($_as as $_av){
				$_fn .= $comma; $comma = ', ';
				/**
				 * 布尔
				 */
				if (is_bool($_av)){
					$_fn .= $_av ? 'true' : 'false';
				}
				/**
				 * 字符
				 */
				else {
					if (is_numeric($_av) || is_string($_av)){
						$_av = str_replace(array("\n", "\r", "\t"), array('<br />', '', ' '), $_av);
						$_av = addslashes(stripslashes($_av));
					} else {
						$_av = '';
					} $_fn .= '"'.$_av.'"';
				}
			} $_fn .= ');';
			/**
			 * 返回HTML-SCRIPT
			 */
			$html  = '<html>';
			$html .= '<head><title>WSCORE-FORM-CALLBACK</title><meta charset="utf-8" /></head>';
			$html .= '<body><script type="text/javascript">try{';
			$html .= $_fn;
			$html .= '}catch(err){}</script></body>';
			$html .= '</html>';
			echo $html;
		} exit;
	}
}
/**
 * 公共静态DAO/MySQL
 */

class wsd {
	/**
	* 默认数据库
	*/
	private static $_db = 'db';
	private static $_db_default = 'db';
	/**
	* 分页设置
	*/
	private static $_mulipages = array();
	public static function pages(){
		return self::$_mulipages;
	}
	/**
	* 指定数据库
	*/
	public static function db($db = ''){
		self::$_db = $db;
	}
	/**
	* 查询条件标准
	*/
	private static function criteria($p){
		/**
		* 格式化条件
		* @param array $p, 接受参数
		* @return null, 无效参数时返回
		*/
		$c = new CDbCriteria; $_err = true; is_array($p) || $p = array(); if (count($p) == 0){
			return $c;
		}
		/**
		* 系列化
		*/
		foreach ($p as $k => $v){
			/**
			* 数组类IN查询
			* @example $p = array('field' => array(1, 2, 3))
			*/
			if (is_array($v)){
				$c->addInCondition($k, $v);
			}
			/**
			* 其它
			*/
			else {
				/**
				* 字段
				* @example $p = array('field' => '^alias_field')
				*/
				if (preg_match("/^\^/", $v)){
					$v = substr($v, 1);
					$c->addCondition($k.' = '.$v);
				} 
				/**
				* 字段
				* @example $p = array('field' => 1)
				* @example $p = array('field' => 'string')
				*/
				else {
					$c->addCondition($k.' = :'.$k);
					$c->params[':'.$k] = $v;
				}
			}
		} 
		/**
		* 返回序列化
		*/		
		return $c;
	}
	/**
	* MYSQL://CRUD
	* @method C, 添加
	* @method D, 删除
	* @method R, 读取
	* @method U, 更新
	*/
	public static function C($t, $f, $i = false){
		self::$_db || self::$_db = self::$_db_default;
		/**
		* 添加记录
		* @param string $t, 表名
		* @param array $f, 字段集
		* @param string $i, 最后AI编号
		*/
		A(self::$_db)->createCommand()->insert('{{'.$t.'}}', $f); if ($i){
			$id = A(self::$_db)->getLastInsertID();
			/**
			* 返回编号
			*/
			if (is_string($i)){
				$_ai = array($i => $id);
			} else {
				$_ai = array('_auto_increment' => $id);
			}
			/**
			* 合并AI到
			*/
			$f = array_merge($_ai, $f);
		} self::db(); return $f;
	}
	public static function D($t, $f){
		self::$_db || self::$_db = self::$_db_default;
		/**
		* 简易删除
		* @param string $t, 表名
		* @param array $f, 字段条件
		* @return int, 实际被删除数量
		*/
		$r = 0; $c = self::criteria($f); if ($c){
			$r = A(self::$_db)->createCommand()->delete('{{'.$t.'}}', $c->condition, $c->params);
		} self::db(); return $r;
	}
	public static function R($t, $f, $o = false){
		self::$_db || self::$_db = self::$_db_default;
		/**
		* 简易读取
		* @param string $t, 表名
		* @param array $f, 字段条件
		* @param boolean $o, 是否提取一条Once
		* @return array, 符合条件记录
		*/
		$r = array(); 
		$c = self::criteria($f); if ($c){
			$d = A(self::$_db)->createCommand()->from('{{'.$t.'}}')->where($c->condition, $c->params);
			$r = $o ? $d->queryRow() : $d->queryAll();
		} self::db(); return $r;
	}
	public static function U($t, $f, $w){
		self::$_db || self::$_db = self::$_db_default;
		/**
		* 快速修改
		* @param string $t, 表名
		* @param array $f, 变更
		* @param array $w, 条件
		* @return int, 数量(被更新记录总数)
		*/
		$r = 0; if (is_array($f) && count($f)){
			$c = self::criteria($w); if ($c){
				$r = A(self::$_db)->createCommand()->update('{{'.$t.'}}', $f, $c->condition, $c->params);
			}
		} self::db(); return $r;
	}
	/**
	 * 添加/减操作
	 */
	public static function P($t, $f, $w){
		$sql = "UPDATE {{".$t."}} SET "; $comma = ''; foreach ($f as $k => $v){
		$sql .= $comma; $comma = ', ';
		$sql .= $k.' = '; $v = (string) $v; if (preg_match("/^[\-][0-9\.]+$/", $v)){
		$sql .= $k.' - '.abs($v * 1); } else if (preg_match("/^[\+][0-9\.]+$/", $v)){
		$sql .= $k.' + '.abs($v * 1); } else {
		$sql .= "'".$v."'"; } } $comma = ' WHERE '; foreach ($w as $k => $v){
		$sql .= $comma; $comma = ' AND ';
		$sql .= $k.'="'.$v.'"';}
		self::$_db || self::$_db = self::$_db_default;
		$r = A(self::$_db)->createCommand($sql)->execute();
		self::db();
		return $r;
	}
	/**
	* MYSQL://SELECT
	* @property array $_SP_RESULT, 分页结果
	* @property array $_SP_CONFIG, 查询分页配置
	* @method S, 查询
	* @method SP, 分页初始化
	*/
	public static $_SP_RESULT = array();
	private static $_SP_CONFIG = array();
	public static function S($p, $_cache = false, $_callback = null){
		self::$_db || self::$_db = self::$_db_default;
		/**
		* 接受参数
		* @param array $p, 配置参数
		*              string from, 表名称/必须
		*              string select, [可选]查询字段
		*              array where, [可选]查询条件
		*              array order, [可选]结果排序
        *              array group, [可选]分组
		*              array joins, [可选]JOIN联表
		*              boolean joincount, [可选]统计时连带JOIN
        *              string fieldcount, [可选] COUNT($fieldcount)
		*              int limit, [可选]提取量
		*              int offset, [可选]起始偏移
		* @param boolea $_cache, 是否缓存
		*/
		$r = array(); 
		is_array($p) || $p = array(); if (wsc::isarr($p, 'from') || wsc::isarr($p, 'table')){
			/**
			* JOIN参数统计初始化
			*/
			$p['joincount'] = isset($p['joincount']) && is_bool($p['joincount']) ? $p['joincount'] : false;
			/**
			* SQL初始化
			*/
			$sql  = 'SELECT ';
			$count = 'SELECT COUNT(*) ';
            if(wsc::isarr($p, 'fieldcount')){
                $count = 'SELECT COUNT('.$p['fieldcount'].') ';
            }
			/**
			* 选字段[可选]
			* @example $p[select] = 't1.f1, t2.f2';
			*/
			$sql .= wsc::isarr($p, 'select') ? $p['select'] : '*';
			$sql .= ' FROM ';
			$count .= ' FROM ';
			/**
			* 兼容WDC::WDAO
			*/
			wsc::isarr($p, 'table') && !wsc::isarr($p, 'from') && $p['from'] = & $p['table'];
			/**
			* 指定表
			* @example $p[from] = 'table t1';
			* @example $p[from] = 'table AS t1';
			*/
			$tbi = 0; $tbs = $counts = ''; foreach (explode(',', $p['from']) as $from){
				$from = trim($from); 
                if ($from){
                    $from_str = strchr($from, '(');
                    if(!empty($from_str)){
                        /**
                        * 子查询
                        * @example $p[from] = '( SELECT * FROM {{wwq_message}} ORDER BY postime DESC ) m';
                        */
                        $sql .= $from;
                        $count .= $from;
                        $from_arr = explode(')', $from);
                        $_from['alias'] = trim(wsc::isarr($from_arr, 1));
                        $tbi++;
                    }else{
                        $_from = self::ST($from);
                    }
                    /**
                    * 返回
                    */
                    if (wsc::isarr($_from, 'table')){
                        $tbi++; 
                        /**
                        * 资料表
                        */
                        $sql .= $tbs; $tbs = ', ';
                        $sql .= '{{'.$_from['table'].'}}'; $_from['alias'] && 
                        $sql .= ' '.$_from['alias'];
                        /**
                        * 统计表
                        */
                        $count .= $counts; $counts = ', ';
                        $count .= '{{'.$_from['table'].'}}'; $_from['alias'] && 
                        $count .= ' '.$_from['alias'];
                        /**
                        * [LEFT|RIGHT|INNER]JOIN 
                        * @param array $p[joins] = array(
                        *     'table' => array(
                        *         0 => array('table' => '', 'where' => '', 'type' => 'LEFT|RIGHT|INNER'), 
                        *         1 => array(...)
                        *              .......
                        *         n => array(...)
                        *     )
                        * )
                        */
                    }
                    if(wsc::isarr($_from, 'alias')){
                        $_joins = wsc::isarr($p, 'joins.'.$_from['alias']); is_array($_joins) || $_joins = array(); foreach ($_joins as $_join){
                            if (is_array($_join) && wsc::isarr($_join, 'from') && wsc::isarr($_join, 'where')){
                                $_joint = self::ST($_join['from']);
                                if (wsc::isarr($_joint, 'alias')){
                                    $sql .= ' ';
                                    $p['joincount'] && $count .= ' ';
                                    /**
                                    * 添加JOIN
                                    */
                                    $_join['type'] = wsc::isarr($_join, 'type') ? strtoupper($_join['type']) : 'LEFT'; switch ($_join['type']){
                                        case 'INNER' 	: $sql .= 'INNER'; $p['joincount'] && $count .= 'INNER'; break;
                                        case 'RIGHT' 	: $sql .= 'RIGHT'; $p['joincount'] && $count .= 'RIGHT'; break;
                                        default 		: $sql .= 'LEFT'; $p['joincount'] && $count .= 'LEFT'; break;
                                    }
                                    /**
                                    * 表名
                                    */
                                    $sql .= ' JOIN {{'.$_joint['table'].'}}'; $_joint['alias'] && $sql .= ' '.$_joint['alias'];
									if ($p['joincount']){
										$count .= ' JOIN {{'.$_joint['table'].'}}'; $_joint['alias'] && $count .= ' '.$_joint['alias'];
									}
                                    /**
                                    * 条件
                                    */									
                                    $_jw = 'ON'; foreach ($_join['where'] as $_jk => $_jv){
                                        $_jq = self::SW($_jk, $_jv, $_jw); if ($_jq){
                                            $sql .= ' '.$_jq; $p['joincount'] && $count .= ' '.$_jq; $_jw && $_jw = '';
                                        }
                                    }
                                }
                            }
                        }
                    }
				}
			} if ($tbi == 0){
				self::db(); return $r;
			}
			/**
			* 条件
			*/
			if (wsc::isarr($p, 'where')){
				$_pw = 'WHERE'; is_array($p['where']) || $p['where'] = array(); 
                foreach ($p['where'] as $_pk => $_pv){
                    $_pq = self::SW($_pk, $_pv, $_pw); if ($_pq){
						$sql .= ' '.$_pq;
						$count .= ' '.$_pq; $_pw && $_pw = '';
					}
				}
			}
            /**
			* 分组
			* @param array $p['group'] = array('f1', 'f2') <=> GROUP BY f1, f2
			*/
			if (wsc::isarr($p, 'group')){
				is_array($p['group']) || $p['group'] = array(); 
				$_group = '';
				$_comma = ' GROUP BY ';
				foreach ($p['group'] as $_ov){
					$_group .= $_comma; $_comma = ', ';
					$_group .= $_ov;
				} if ($_group){
					$sql .= $_group;
				}
            }
			/**
			* 排序
			* @param array $p['order'] = array('f1' => 0, 'f2' => 0) <=> ORDER BY f1 ASC, f2 ASC
			* @param array $p['order'] = array('f1' => 1, 'f2' => 1) <=> ORDER BY f1 DESC, f2 DESC
			*/
			if (wsc::isarr($p, 'order')){
				is_array($p['order']) || $p['order'] = array(); 
				$_order = '';
				$_comma = ' ORDER BY ';
				foreach ($p['order'] as $_ok => $_ov){
					$_order .= $_comma; $_comma = ', ';
					$_order .= $_ok.' '.($_ov ? 'DESC' : 'ASC');
				} if ($_order){
					$sql .= $_order;
				}
			}
			/**
			* 数据统计
			*/
			if (wsc::isarr($p, 'page.href')){
				$total = (int) A(self::$_db)->createCommand($count)->queryScalar(); 
				$pages = self::SP($p['page'], $total); if ($pages['pages'] == 0){
					self::db(); return $r;
				} else {
					$p['limit'] = $pages['limit'];
					$p['offset'] = $pages['offset'];
				}
			}
			/**
			* 分页
			* @param int $p[limit] = 10 <=> LIMIT 10
			* @param int $p[offset] = 0 <=> OFFSET 0
			*/
			if (wsc::isarr($p, 'limit', '>0')){
				$sql .= ' LIMIT '.$p['limit']; if (wsc::isarr($p, 'offset', '>0')){
					$sql .= ' OFFSET '.$p['offset'];
				}
			}
			/**
			* 读取结果
			*/
			$r = self::SQ($sql, $_cache, $_callback);
		}
		/**
		* 返回空数组
		*/
		self::db(); return $r;
	}
	public static function SP($p, $n){	
		/**
		* 分页配置
		* @param array $p, 接受参数
		*              string href, 分页链接标准/eg: /setting/user?q=r
		*              int page, 当前页
		*              int pages, 总页数
		*              int perpage, 每页数量
		*              int maxlimit, 最大提取数量(如：1000，不论结果有多少，最多只提取1000条)
		* @param int $n, 总数值
		* @return array, 返回分页
		*                int total, 总数
		*                int page, 当前页
		*                int pages, 总页数
		*                int perpage, 每页数
		*                int showpage, 显示页码数
		*                int offset, 偏移量
		*                int limit, 读取量
		*                string link, 链接列表
		*/
		$r = array('total' => $n, 'maxlimit' => 0, 'maxpage' => 0, 'page' => 1, 'pages' => 0, 'perpage' => 25, 'showpage' => 10, 'offset' => 0, 'limit' => 0, 'link' => '');
		/**
		* 总数大于0时
		*/
		if ($n){
			$_comma_link = '?'; if (preg_match("/\?/", $p['href'])){
			$_comma_link = '&amp;'; }
			/**
			* 每页数
			*/
			$p['perpage'] = (int) wsc::isarr($p, 'perpage');
			$p['perpage'] && $r['perpage'] = $p['perpage'];
			$perpage = (int) I('g.perpage'); if ($perpage > 0){
				$r['perpage'] = $perpage;
				$p['href'] .= $_comma_link; $_comma_link = '&amp;';
				$p['href'] .= 'perpage='.$perpage;
			}
			/**
			* 总页数
			*/
			$r['pages'] = ceil($n/$r['perpage']);
			$r['maxpage'] = $r['pages'];
			/**
			* 最大提取量
			*/
			$maxlimit = (int) wsc::isarr($p, 'maxlimit'); if ($maxlimit){
				$r['maxlimit'] = $maxlimit;
				$r['maxpage'] = ceil($r['maxlimit']/$r['perpage']); 
				$r['maxpage'] > $r['pages'] && $r['maxpage'] = $r['pages'];
			} 
			/**
			* 当前页
			*/
			$_page = (int) I('g.page');
			$_page < 1 && $_page = 1;
			$_page > $r['maxpage'] && $_page = $r['maxpage']; $r['page'] = $_page;
			/**
			* 区间值
			*/
			$r['limit'] = $r['perpage'];
			$r['offset'] = ($r['page'] - 1) * $r['limit']; 
			/**
			* 链接范围
			*/
			wsc::isarr($p, 'showpage', '>0') && 
			$r['showpage'] = $p['showpage']; $showpage = (int) I('g.showpage'); 
			if ($showpage > 0){
				$r['showpage'] = $showpage;
				$p['href'] .= $_comma_link; $_comma_link = '&amp;';
				$p['href'] .= 'showpage='.$showpage;
			}
			/**
			* 起始与结束
			*/
			$_begine = 1;
			$_finish = $r['maxpage'];
			if ($r['maxpage'] > $r['showpage']){
				$_half = (int) $r['showpage']/2;
				$_begine = $r['page'] - $_half; $_begine < 1 && $_begine = 1;
				$_finish = $_begine + $r['showpage'] - 1; if ($_finish > $r['maxpage']){
				$_finish = $r['maxpage'];
				$_begine = $_finish - $r['showpage'] + 1; }
			}
			/**
			* 链接标准
			*/
			for ($i = $_begine; $i <= $_finish; $i++){
				$r['link'] .= ' '; if ($i == $r['page']){
				$r['link'] .= '<a href="javascript:void(0)" class="n inline hover">'.$i.'</a>'; } else {
				$r['link'] .= '<a href="'.$p['href'].$_comma_link.'page='.$i.'" class="n inline">'.$i.'</a>'; }
			}
			/**
			* 重置链接
			*/
			self::$_mulipages = $r;
		} return $r;
	}
	/**
	* 执行查询
	* @method SQ, SELECT-QUERY
	*/
	private static function SQ(& $s, & $_cache = array(), & $_callback = array()){
		self::$_db || self::$_db = self::$_db_default;
		/**
		* 接受参数
		* @param string $s, 完整SQL语句
		* @param boolean $_cache, 是否缓存
		* @param callable $_callback, 回调
		*/
		$r = $q = array(); $d = A(self::$_db)->createCommand($s)->query(); while ($q = $d->read()){
			$_callback && $q = C($_callback,array($q));
			$r[] = $q;
		} self::db(); return $r;
	}
	/**
	* 表名解析
	* @method ST, SELECT-TABLE
	*/
	private static function ST(& $s){
		/**
		* 接受参数
		* @param string $s, 表名称, 可能的内容如下
		* @return array $r, 结果返回
		*               string alias, 别名
		*               string table, 表名
		*/
		$r = array('alias' => '', 'table' => '');
		/**
		* 简别名
		* @param string $s = 'table t1'
		*/
		if (preg_match("/^([a-z0-9_]+)(\s+)([a-z0-9+]+)$/i", $s, $m)){
			$r['alias'] = $m[3];
			$r['table'] = $m[1];
		}
		/**
		* 混别名
		* @param string $s = 'table AS t1'
		*/
		else if (preg_match("/^([a-z0-9_]+)(\s+)as(\s+)([a-z0-9+]+)$/i", $s, $m)){
			$r['alias'] = $m[4];
			$r['table'] = $m[1];
		}
		/**
		* 无别名
		* @param string $s = 'table'
		*/
		else if (preg_match("/^([a-z][a-z0-9_]*)$/i", $s)) {
			$r['table'] = $s;
		}
		/**
		* 返回结果
		*/
		return $r;
	}
	/**
	* 查询条件
	* @method SW, SELECT-WHERE
	* @method SWP, SELECT-WHERE-PARSER
	*/
	private static function SW(& $k, & $v, $l = ''){
		/**
		* 接受参数
		* @param int|string $k, 数组索引号或字段名
		* @param any $v, 任意类型/条件匹配项
		* @param any $l, 查询逻辑[WHERE|AND|OR|XOR]
		* @return string $r, 条件语句
		*/
		$r = '';
		/**
		* 简易SQL
		*/
		if (preg_match("/^([0-9]+)$/", $k) && is_string($v)){
			return $l.' '.$v;
		}
		/**
		* 简易转复合参数
		*/
		$p = $v; if (!preg_match("/^([0-9]+)$/", $k)){
			$p = array();
			$p[] = $k;
			$p[] = $v;
		}
		/**
		* 解析条件完成
		*/
		$q = self::SWP($p); if (wsc::isarr($q, 'logic') && wsc::isarr($q, 'query')){
			$r  = $q['logic']; $l && 
			$r  = $l;
			$r .= ' ';
			$r .= $q['query'];
		} unset($p);
		/**
		* 返回
		*/
		return $r;
	}
	private static function SWP(& $p){
		/**
		* 接受参数
		* @param array $p, 查询配置
		*              string [:0], 字段名
		*              string [:1], 条件项
		*              string [:2], 逻辑项(AND|OR|XOR)
		*              string [:3], 逻辑符(默认: 自动, 可选: >|>=|=|<=|<)
		*              string [:4], 字段比较
		* @return array $r, 返回
		*               string logic, 逻辑[AND|OR|XOR]
		*               string query, 条件
		*/
		$r = array('logic' => 'AND', 'query' => ''); is_array($p) || 
		$p = array();
		$i = count($p);
		/**
		* 无效参数
		*/
		if ($i == 0){
			return $r;
		}
		/**
		* 初始化参数
		*/
		$i < 2 && $p[1] = null;
		$i < 3 && $p[2] = false;
		$i < 4 && $p[3] = false;
		$i < 5 && $p[4] = false;
		/**
		* 逻辑
		* @var array $p = array('key', 'val')
		* @var array $p = array('key', 'val', 'OR')
		* @var array $p = array('key', 'val', 'XOR')
		*/
		if (is_string($p[2])){
			$r['logic'] = strtoupper($p[2]);
		} if (is_string($p[3])){
			$p[3] = strtoupper($p[3]);
		}
		/**
		* NULL查询
		* @var array $p = array('key')
		* @var array $p = array('key', null)
		*/
		if (is_null($p[1])){
			$r['query'] = $p[0].' IS NULL';
			return $r;
		}
		/**
		* 多表字段比较
		* @var array $p = array('key', 'val', false, false, true)
		* @example WHERE t1.field1 = t2.field1
		*/
		if ($i >= 5 && is_bool($p[4]) && $p[4]){
			$r['query'] .= $p[0].' = '.$p[1];
			return $r;
		}
		/**
		* 数组
		* @var array $p = array('key', array(1, 2, 3))
		* @var array $p = array('key', array(1, 2, 3), 'OR')
		* @var array $p = array('key', array(1, 2, 3), 'OR', 'NOT IN')
		*/
		if (is_array($p[1])){
			$_ai = count($p[1]);
			/**
			* NOT-NULL查询
			* @var array $p = array('key', array()) <=> SQL: WHERE ... AND key IS NOT NULL
			*/
			if ($_ai == 0){
				$r['query'] = $p[0].' IS NOT NULL';
				return $r;
			}
			/**
			* 单数组
			*/
			if ($_ai == 1){
				$r['query'] = $p[0].' = '; if (is_numeric($p[1][0])){
				$r['query'] .= $p[1][0]; } else {
				$r['query'] .= "'".addslashes(stripslashes($p[1][0]))."'"; }
				return $r;
			}
			/**
			* BETWEEN...AND..
			* @var array $p = array('key', array(1, 10), 'AND', 'BETWEEN') <=> SQL: WHERE ... AND key BETWEEN 1 AND 10
			*/
			if ($p[3] == 'BETWEEN' && $_ai == 2){
				$r['query'] = '('.$p[0].' BETWEEN '.$p[1][0].' AND '.$p[1][1].')';
				return $r;
			}
			/**
			* IN/NOTIN
			* @var array $p = array('key', array(1, 10), 'AND', 'IN') <=> SQL: WHERE ... AND key IN (1, 10)
			* @var array $p = array('key', array(1, 10), 'AND', 'NOTIN') <=> SQL: WHERE ... AND key NOT IN (1, 10)
			*/
			$_comma = '';
			$r['query']  = $p[0].' ';
			$r['query'] .= $p[3] == 'NOTIN' ? 'NOT IN' : 'IN';
			$r['query'] .= ' ('; foreach ($p[1] as $_pv){
			$r['query'] .= $_comma; $_comma = ', ';
			$r['query'] .= is_numeric($_pv) ? $_pv : "'".addslashes(stripslashes($_pv))."'"; }
			$r['query'] .= ')';
			return $r;
		}
		/**
		* LIKE/NOTLIKE/SEARCH
		* @var array $p = array('key', 'val', false, 'LIKE') <=> SQL: WHERE ... AND key LIKE '%val%'
		* @var array $p = array('key', 'val', 'AND', 'LIKE') <=> SQL: WHERE ... AND key LIKE '%val%'
		* @var array $p = array('key', 'val', 'OR', 'LIKE', '^') <=> SQL: WHERE ... OR key LIKE 'val%'
		* @var array $p = array('key', 'val', 'OR', 'LIKE', '$') <=> SQL: WHERE ... OR key LIKE '%val'
		*/
		if ($p[3] == 'LIKE' || $p[3] == 'NOTLIKE' || $p[3] == 'SEARCH'){
			$r['query'] .= $p[0]; $p[3] == 'NOTLIKE' && 
			$r['query'] .= ' NOT';
			$r['query'] .= ' LIKE ';
			$r['query'] .= "'";
			switch ($p[4]){
				case '^' : $r['query'] .= $p[1].'%'; break;
				case '$' : $r['query'] .= '%'.$p[1]; break;
				default  : $r['query'] .= '%'.$p[1].'%'; break;
			} $r['query'] .= "'"; return $r;
		}
		/**
		* 普通
		* @var array $p = array('key', 'val') <=> SQL: WHERE ... AND key = 'val'
		* @var array $p = array('key', 'val', 'AND') <=> SQL: WHERE ... AND key = 'val'
		* @var array $p = array('key', 'val', 'OR', '>') <=> SQL: WHERE ... OR key > val
		* @var array $p = array('key', 'val', 'OR', '!=') <=> SQL: WHERE ... OR key != 'val'
		*/
		$r['query'] .= $p[0].' ';
		$r['query'] .= $p[3] ? $p[3] : '=';
		$r['query'] .= ' ';
		$r['query'] .= is_numeric($p[1]) ? $p[1] : "'".addslashes(stripslashes($p[1]))."'";
		return $r;
	}
}
/**
* 初始化
*/
wsc::init();